/**
 * 
 */
package com.module.hq.bus.flyweights;

import com.dalonedrau.pool.PooledStringBuilder;
import com.dalonedrau.pool.StringBuilderPool;

/**
 * @author Donald
 *
 */
public final class HQTerrainTypes {
	/** the list of terrain names. */
	private char[][] typeNames;
	/** the one and only instance of the <code>HQTerrainTypes</code> class. */
	private static HQTerrainTypes	instance;
	/**
	 * Gives access to the singleton instance of {@link HQTerrainTypes}.
	 * @return {@link HQTerrainTypes}
	 */
	public static HQTerrainTypes getInstance() {
		if (HQTerrainTypes.instance == null) {
			HQTerrainTypes.instance = new HQTerrainTypes();
		}
		return HQTerrainTypes.instance;
	}
	/**
	 * Gets a terrain's name.
	 * @param id the terrain's reference id
	 * @return <code>int</code>
	 * @throws Exception if the terrain was never loaded
	 */
	public String getTerrainName(final int id) throws Exception {
		if (typeNames == null) {
			typeNames = new char[0][];
		}
		return new String(typeNames[id]);
	}
	/**
	 * Gets a terrain's reference id.
	 * @param type the name of the terrain.
	 * @return <code>int</code>
	 * @throws Exception if the terrain was never loaded
	 */
	public int getTerrainId(final String type) throws Exception {
		if (typeNames == null) {
			typeNames = new char[0][];
		}
		int index = -1;
		for (int i = 0; i < typeNames.length; i++) {
			// check to see if index is not null
			if (typeNames[i] != null) {
				// compare index with type name to added
				String s = new String(typeNames[i]);
				if (s.equalsIgnoreCase(type)) {
					// terrain already added. mark index
					index = i;
					break;
				}
				s = null;
			}
		}
		if (index == -1) {
			// type was never loaded. throw exception
			PooledStringBuilder sb = 
				StringBuilderPool.getInstance().getStringBuilder();
			sb.append("Terrain type ");
			sb.append(type);
			sb.append(" was never added to master list.");
			Exception ex = new Exception(sb.toString());
			sb.returnToPool();
			throw ex;
		}
		return index;
	}
	/**
	 * Adds a terrain by name.  If the terrain already exists, it is not added.
	 * @param type the name of the terrain
	 */
	public void addTerrain(final String type) {
		if (typeNames == null) {
			typeNames = new char[0][];
		}
		int index = -1;
		for (int i = 0; i < typeNames.length; i++) {
			// check to see if index is not null
			if (typeNames[i] != null) {
				// compare index with type name to added
				String s = new String(typeNames[i]);
				if (!s.equalsIgnoreCase(type)) {
					continue;
				}
				// terrain already added. mark index
				index = i;
				s = null;
				break;
			}
		}
		if (index == -1) {
			// terrain never added. extend the array
			char[][] dest = new char[typeNames.length + 1][];
			System.arraycopy(typeNames, 0, dest, 0, typeNames.length);
			dest[typeNames.length] = type.toCharArray();
			typeNames = dest;
			dest = null;
		}
	}
}
